﻿using Craftsman.Core.Domain.Repositories;
using Craftsman.xCoronavirus.Domain.Contract;
using Craftsman.xCoronavirus.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Craftsman.xCoronavirus.Infrastructure
{
    public class QuestionnaireRepository : IQuestionnaireRepository
    {
        private IRepository<Questionnaire, string> _repoQuestionnaire;
        private IRepository<QuestionnaireContact, string> _repoQuestionnaireContact;
        private IRepository<QuestionnaireHospital, string> _repoQuestionnaireHospital;
        private IRepository<QuestionnaireMaterialDemand, string> _repoQuestionnaireMaterialDemand;

        public QuestionnaireRepository(
            IRepository<Questionnaire, string> repoQuestionnaire,
            IRepository<QuestionnaireContact, string> repoQuestionnaireContact,
            IRepository<QuestionnaireHospital, string> repoQuestionnaireHospital,
            IRepository<QuestionnaireMaterialDemand, string> repoQuestionnaireMaterialDemand
        )
        {
            _repoQuestionnaire = repoQuestionnaire;
            _repoQuestionnaireContact = repoQuestionnaireContact;
            _repoQuestionnaireHospital = repoQuestionnaireHospital;
            _repoQuestionnaireMaterialDemand = repoQuestionnaireMaterialDemand;
        }

        public Questionnaire CreatQuestionnaire(Questionnaire entity)
        {
            _repoQuestionnaire.Insert(entity);
            if (entity.Hospital != null)
            {
                _repoQuestionnaireHospital.Insert(entity.Hospital);
            }
            if (entity.MaterialDemands != null && entity.MaterialDemands.Count > 0)
            {
                foreach (var item in entity.MaterialDemands)
                {
                    _repoQuestionnaireMaterialDemand.Insert(item);
                }
            }
            if (entity.Contacts != null && entity.Contacts.Count > 0)
            {
                foreach (var item in entity.Contacts)
                {
                    _repoQuestionnaireContact.Insert(item);
                }
            }
            return entity;
        }

        public bool ExistQuestionnaire(Expression<Func<Questionnaire, bool>> predicate)
        {
            return !(_repoQuestionnaire.FirstOrDefault(predicate) == null);
        }

        public List<Questionnaire> GetAllQuestionnaire(QuestionnaireStatus status, bool withDetails = false)
        {
            //GetAllList(Expression<Func<TEntity, bool>> predicate)
            //var allQuestionnaire = _repoQuestionnaire.GetAllList();
            var allQuestionnaire = _repoQuestionnaire.GetAllList(q => q.Status == status);
            if (allQuestionnaire != null && allQuestionnaire.Count > 0)
            {
                List<string> ids = allQuestionnaire.Select(a => a.Id).ToList();
                var contacts = _repoQuestionnaireContact.GetAllList(p => ids.Contains(p.QuestionnaireId));
                var hospitals = _repoQuestionnaireHospital.GetAllList(p => ids.Contains(p.QuestionnaireId));
                var materialDemands = _repoQuestionnaireMaterialDemand.GetAllList(p => ids.Contains(p.QuestionnaireId));
                allQuestionnaire.ForEach(a =>
                {
                    a.Contacts = contacts?.FindAll(c => a.Id == c.QuestionnaireId);
                    a.Hospital = hospitals?.FirstOrDefault(c => a.Id == c.QuestionnaireId);
                    a.MaterialDemands = materialDemands?.FindAll(c => a.Id == c.QuestionnaireId);
                });

            }


            return allQuestionnaire;
        }

        public Questionnaire GetQuestionnaire(string guid)
        {
            var questionnaire = _repoQuestionnaire.Get(guid);
            if (questionnaire == null) return null;
            questionnaire.MaterialDemands = _repoQuestionnaireMaterialDemand.GetAllList(x => x.QuestionnaireId == questionnaire.Id);
            questionnaire.Contacts = _repoQuestionnaireContact.GetAllList(x => x.QuestionnaireId == questionnaire.Id);
            var hospital = _repoQuestionnaireHospital.GetAllList(x => x.QuestionnaireId == questionnaire.Id)?.FirstOrDefault();
            questionnaire.Hospital = hospital == null ? new QuestionnaireHospital() { Name = "" } : hospital;
            return questionnaire;
        }

        public Questionnaire UpdateQuestionnaire(Questionnaire entity)
        {
            _repoQuestionnaire.Update(entity);
            if (entity.Hospital != null)
            {
                _repoQuestionnaireHospital.InsertOrUpdate(entity.Hospital);
            }
            if (entity.MaterialDemands != null && entity.MaterialDemands.Count > 0)
            {
                foreach (var item in entity.MaterialDemands)
                {
                    _repoQuestionnaireMaterialDemand.InsertOrUpdate(item);
                }
            }
            if (entity.Contacts != null && entity.Contacts.Count > 0)
            {
                foreach (var item in entity.Contacts)
                {
                    _repoQuestionnaireContact.InsertOrUpdate(item);
                }
            }
            return entity;
        }

        public Questionnaire GetQuestionnaireByFormCode(string form_code)
        {
            var questionnaires = _repoQuestionnaire.GetAllList(x => x.FormCode == form_code);
            if (questionnaires == null || questionnaires.Count <= 0) return null; 
            return questionnaires[0];
        }
    }
}
